import pygame
from didiball.sprites.PassiveSprite import PassiveSprite
import didiball.Physics2D as p2d

class ActiveSprite(PassiveSprite):

    def __init__(self, dynamics, team, basepoint, startpoint, sprite_sheet, caption='b'):
        self.__basepoint= basepoint
        self.__startpoint= startpoint
        self.__team = team
        self.__sprite_sheet= sprite_sheet
        self.__surface= sprite_sheet.get_default_img()
        PassiveSprite.__init__(self, self.get_startpoint(), 0, 0, self.__surface, dynamics)
        self.__dynamics = dynamics
        self.__acceleration = 0.0025
        self.__caption = caption
        self.__fonth = pygame.font.SysFont(None, 25)
        self.__fontu = pygame.font.SysFont(None, 15)
        self.fg = self.__surface.copy()
        
        self.unhighlight()

    def hoof(self,other):
        x= (other.get_speed_angle() - self.get_speed_angle()) / 3 * (other.get_speed_magnitude() / other.get_max_speed())
        other.set_speed_angle(self.get_speed_angle()+x)
        other.set_speed_magnitude(other.get_max_speed()) #+50000)

    #TODO: make this cleverer!?
    def pass_to(self,ball,player):
        ball.set_speed_angle(p2d.calc_angle(self.get_pos_xy(),player.get_pos_xy()))
        ball.set_speed_magnitude(ball.get_max_speed()*0.75) #+50000)
        

    def get_basepoint_adjusted(self,ball,r2l):
        ballx= ball.get_pos_xy()[0]
        bally= ball.get_pos_xy()[1]
        pitchwidth= self.__team.get_pitch().get_rect().width
        pitchheight= self.__team.get_pitch().get_rect().height

        offx = ballx - pitchwidth/2
        
        #if r2l==True:
        #    offx = offx * -1
            
        offy = bally - pitchheight/2
        px = (offx/10)
        py = (offy/10)
        #if r2l==False:
        #    print "x:{0},y:{1},w:{2},h:{3},px:{4},py:{5},bpx:{6},bpy:{7}".format(ballx,bally,pitchwidth,pitchheight,px,py,self.__basepoint[0],self.__basepoint[1])
        
        #self.get_pos_xy()
        return (self.__basepoint[0]+px,self.__basepoint[1]+py)
    
    def get_basepoint(self):
        return self.__basepoint
    
    def get_startpoint(self):
        return self.__startpoint
#	return (self.__zone.left+self.__zone.width*(2-self.__team.get_id())/3),(self.__zone.top+self.__zone.height/2)

#    def move_base(self):
#        self.set_pos_xy(self.get_basepoint())
        
    def move_start(self):
        self.set_pos_xy(self.get_startpoint())

    def avoid(self,tick_ms,other):
        if other.is_moving_towards(self):
                #rotate other's motion by 90 degrees
                self.set_speed_angle (90+other.get_speed_angle())
                #self.refresh_surface()
                self.set_speed_magnitude(self.get_max_speed()/2)
                #self.move(tick_ms,pitch)

    #used in ai!
    def attack(self,tick_ms,other_item):
        
        sang= p2d.calc_angle(self.get_pos().get_xy(), other_item.get_pos().get_xy())
        sang = self.kerb(sang,self.__team.is_r2l())
        #print sang
        #if not p2d.angle_is_fwd(sang, self.__team.is_r2l()):
        #    print sang
        self.set_speed_angle (sang)
        self.set_speed_magnitude(self.get_max_speed())
        
        #self.refresh_surface(tick_ms)

    def kerb(self,angle,r2l):
        #go back if it's behind you, and generally try to keep behind the ball.
        #True is l2r
        if r2l==True:
            if angle > 90 and angle < 270:
                return 165
            elif angle < 75:
                return angle +15
            elif angle > 285:
                return angle -15
            else:
                return 195
        elif r2l==False:
            if (angle < 90 or angle > 270):
                return 345
            elif angle > 105:
                return angle +15
            elif angle < 265:
                return angle -15
            else:
                return 15
                
    #tomaybe: investgate Vector etc
    def move_towards(self,tick_ms,destxy):
        self.set_speed_magnitude(0)
        destx,desty = destxy 
        startx,starty= self.get_pos().get_xy()
        diffx= destx-startx
        max= self.get_max_speed() * 5
        if diffx > max:
                diffx = max
        elif diffx < -max:
                diffx = -max
        diffy= desty-starty
        if diffy > max:
                diffy = max
        elif diffy < -max:
                diffy = -max
        self.set_pos_xy((diffx+startx,diffy+starty))
        
        #sang = p2d.calc_angle((startx,starty), destxy)
        #self.set_speed_angle (sang)
        #self.refresh_surface(sang)
    
    def reblit(self):
        self.get_surface().blit( self.fg, (0,0) )
    
    def highlight(self):
        self.__active=True
        self.__sprite_sheet.replace_sheet_colour((77,77,77),(240,240,40))
        self.reblit()
        label = self.__fontu.render(self.__caption,1,(240,240,20))
        self.get_surface().blit( label, (20,0) )

    def unhighlight(self):
        self.__active=False
        self.__sprite_sheet.replace_sheet_colour((240,240,40),(77,77,77))
        self.reblit()
        label = self.__fontu.render(self.__caption,1,(255,255,255))
        self.get_surface().blit( label, (20,0) )

    def refresh_surface(self,tick_ms=None,angle=None,velocity=None):
        if(angle is None):
            angle= self.get_speed_angle()
        if self.__active:
            velocity=1
        self.__surface.fill(self.__sprite_sheet.get_bg_colour())
        self.__surface.set_colorkey(self.__sprite_sheet.get_bg_colour())
        self.fg= self.__sprite_sheet.get_img(angle, velocity)
        self.reblit()
        
    def get_img(self):
        return self.fg
        
    def mod( self, x, y, tick_ms):
        # friction
        PassiveSprite.friction(self,tick_ms)
        #print "doing friction then moving "
        vx,vy = self.get_speed_xy()
        vx += x*self.__acceleration*tick_ms
        vy += y*self.__acceleration*tick_ms
        sang= p2d.calc_angle_from_O((vx,vy))
        self.set_speed_angle(sang)
        #if sang != 0.0:
            #print "sang: ",sang
        new_speed = p2d.calc_distance_from_O((vx,vy))
        if new_speed<=self.get_max_speed():
            self.set_speed_magnitude (new_speed)
 
    def move( self, tick_ms, pitch):
        #print "moving! ",self.__team," ",self.__caption
        touched = 0
        old_pos= self.get_pos_xy()
 
        new_pos = self.get_pos()+tick_ms*self.get_speed()
        px,py = new_pos.get_xy()

        sang= p2d.calc_angle(old_pos,(px,py))
        
#        limit_zone= self.__zone 
        limit_zone= pitch.get_rect()
        margin=10
        lt= limit_zone.top-margin-self.get_rect().width
        lb= limit_zone.top+limit_zone.height+margin
        limit_left= limit_zone.left-margin-self.get_rect().height
        limit_right= limit_zone.left+limit_zone.width+margin
        if (py < lt+self.get_height()*0.5):
            touched = 1
            py = lt+self.get_height()*0.5
        elif (py > lb-self.get_height()*0.5):
            touched = 1
            py = lb-self.get_height()*0.5

        
        if (px < limit_left):
            touched = 1
            px = limit_left
        elif (px > limit_right):
            touched = 1
            px = limit_right
             
        if (touched==1):
            #print "Bounced: {0}".format(self)
            self.set_speed_magnitude(p2d.calc_distance(old_pos,(px,py))/tick_ms)
            
        self.set_speed_angle(p2d.calc_angle(old_pos,(px,py)))
        self.set_pos_xy((px,py))
        #blit to radar
        #if old_pos != (px,py):
        #	self.__radar.blit_item(old_pos,(px,py),(0,0,0)) 
        #return enough data for blitting radar
        
        return old_pos,(px,py)
        
    def __str__(self):
        return "P: "+self.__caption
    def get_caption(self):
        return self.__caption 
 
